package com.dliu.javadesign.structure.proxy;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @author yanglei
 * date 2021/4/2 15:38
 */
public interface House {
    void sell();

    static void main(String[] args) {
        HouseMaster master = new HouseMaster();
        master.sell();
        System.out.println();

        //静态代理
        StaticHouseProxy proxy = new StaticHouseProxy(master);
        proxy.sell();
        System.out.println();

        //动态代理
        InvocationHandler dynamicHouseProxy = new DynamicHouseProxy(master);
        House proxyInstance = (House)Proxy.newProxyInstance(dynamicHouseProxy.getClass().getClassLoader(),
                new Class[]{House.class},
                dynamicHouseProxy);
        proxyInstance.sell();
        System.out.println();

        //CGLib代理
        CGLibHouseProxy cgLibHouseProxy = new CGLibHouseProxy(master);
        HouseMaster cglibCreator = cgLibHouseProxy.myCglibCreator();
        cglibCreator.sell();
    }
}
/** 业主自己卖房子 */
class HouseMaster implements House{
    @Override
    public void sell() {
        System.out.println("业主120万卖房子");
    }
}

/** 静态代理 */
class StaticHouseProxy implements House {
    private final House houseMaster;

    public StaticHouseProxy(House houseMaster){
        this.houseMaster = houseMaster;
    }
    @Override
    public void sell() {
        System.out.println("静态中介找到人买");
        houseMaster.sell();
    }
}

/** JDK动态代理 */
class DynamicHouseProxy implements InvocationHandler {
    private final House house;

    public DynamicHouseProxy(House house){
        this.house = house;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("动态中介找到人买");
        Object invoke = method.invoke(house, args);
        return invoke;
    }
}

/** CGLib动态代理 */
class CGLibHouseProxy implements MethodInterceptor {
    private final HouseMaster houseMaster;

    public CGLibHouseProxy(HouseMaster houseMaster) {
        this.houseMaster = houseMaster;
    }

    public HouseMaster myCglibCreator(){
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(HouseMaster.class);
        enhancer.setCallback(this);
        return (HouseMaster)enhancer.create();
    }

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("CGLib中介找到人买");
        Object invoke = method.invoke(houseMaster, objects);
        return invoke;
    }
}




